<?php
/**
 * 第三方API[WebApi]
 * @author wsfuyibing <websearch@163.com>
 * @source [PATH]project/module/wapi.php
 * @date 2014-07-18
 */
class WapiModule{
	private $_wpull_key = 'aid';
	/**
	 * 读取系统用
	 */
	public function wapiGet($p){
		$w = array();
		/**
		 * 查询条件
		 */
		wsc::isarr($p, 'wid', '>0') && $w['w.wid'] = $p['wid'];
		wsc::isarr($p, 'wstatus', '>=0') && $w['w.wstatus'] = $p['wstatus'];
		/**
		 * 返回
		 */
		return wsd::S(array('from' => 'wapi w', 'where' => $w));
	}
	/**
	 * 用户应用管理
	 */
	public function wappDecode($p){
		/**
		 * 将字符串转数组
		 */
		$a = array(); $s = preg_replace("/&amp;/i", '&', $p['asetting']); foreach (explode('&', $s) as $s1){
			$s1 = trim($s1); if ($s1 != ''){
				$s2 = explode('=', $s1); $si = count($s2);
				$a[$s2[0]] = $si > 1 ? $s2[1] : '';
			}
		} $p['asetting'] = $a;
		/**
		 * 重置返回
		 */
		return $p;
	}
	/**
	 * 删除用户应用
	 * @param array $p, 接受参数
	 *              int aid, 应用ID
	 *              int auid, 隶属用户
	 * @return array, 被删除应用
	 */
	public function wappDel($p){
		$r = array();
		/**
		 * 查询条件
		 */
		if (wsc::isarr($p, 'aid', '>0') || wsc::isarr($p, 'auid', '>0')){
			$r = $this->wappGet($p);
		}
		/**
		 * 读取列表
		 */
		if (wsc::isarr($r, '0.aid', '>0')){
			/**
			 * 删除应用
			 */
			foreach ($r as $ra){
				wsd::D('wapi_reply', array('aid' => $ra['aid']));
				wsd::D('wapi_app', array('aid' => $ra['aid']));
			}
		}
		/**
		 * 返回
		 */
		return $r;
	}
	/**
	 * 读取用户应用
	 * @param array $p, 接受参数
	 *              int aid, 应用ID
	 *              int awid, 系统应用
	 *              int auid, 隶属用户
	 *              int astatus, 应用状态(0: 停用, 1: 启用)
	 * @return array, 应用列表
	 */
	public function wappGet($p){
		$r = $w = array();
		/**
		 * 查询条件
		 */
		wsc::isarr($p, 'aid', '>0') && $w['a.aid'] = $p['aid'];
		wsc::isarr($p, 'awid', '>0') && $w['a.awid'] = $p['awid'];
		wsc::isarr($p, 'auid', '>0') && $w['a.auid'] = $p['auid'];
		wsc::isarr($p, 'astatus', '>=0') && $w['a.astatus'] = $p['astatus'];
		/**
		 * 至少1个条件
		 */
		if (count($w) === 0){
			return $r;
		}
		/**
		 * 读取列表
		 */
		$s = array('from' => 'wapi_app a', 'where' => $w);
		/**
		 * 联表
		 */
		$s['joins'] = array(
			'a' => array(
				array(
					'from' => 'wapi w', 'where' => array(
						array('w.wid', 'a.awid', null, null, true)
					)
				)
			)
		);
		/**
		 * 分页
		 */
		if (wsc::isarr($p, 'page.href')){
			$s['page'] = $p['page'];
		}
		/**
		 * 返回
		 */
		return wsd::S($s, null, array($this, 'wappDecode'));
	}
	/**
	 * 添加|修改用户应用
	 * @param array $p, 接受参数
	 *              int aid, 应用编号
	 *              int auid, 应用所有人
	 * @param boolean $n, 是否为添加[New]模式
	 * @return array, 最近一次保存应用
	 * @note 错误返回时, 编号与错误描述
	 *       1: 系统应用不存在
	 *       2: 系统应用已停用
	 */
	public function wappSet($p, $n = false){
		$f = array();
		/**
		 * 自动回复类型
		 */
		$reply = '';
		/**
		 * 添加模式
		 */
		if ($n){
			$f['awid'] = I('p.awid');
			$f['auid'] = $p['auid'];
			/**
			 * 应用存在与状态
			 * @note 检查系统应用存在与状态
			 */
			$api = $this->wapiGet(array('wid' => $f['awid'])); if (wsc::isarr($api, '0.wid', '>0')){
				if (wsc::isarr($api, '0.wstatus', '=0')){
					return array('errno' => 2, 'error' => L('WAPI_API_DISABLED'));
				} else {
					$reply = $api[0]['wtype'];
				}
			} else {
				return array('errno' => 1, 'error' => L('WAPI_API_NULL'));
			}
		}
		/**
		 * 状态变更
		 */
		$f['astatus'] = I('p.astatus') ? 1 : 0;
		$f['areply'] = I('p.areply') ? 1 : 0;
		/**
		 * 令牌[仅在添加时生成]
		 */
		if ($n){
			$f['atoken'] = substr(md5(microtime(true)), 8, 16);
		}
		/**
		 * 账号配置
		 */
		$f['asetting'] = $comms = ''; $fas = array('appid' => I('p.appid'), 'appkey' => I('p.appkey'), 'appname' => I('p.appname')); foreach ($fas as $sk => $sv){
			if ($sv != ''){
				$f['asetting'] .= $comms; $comms = '&';
				$f['asetting'] .= $sk.'='.$sv;
			}
		}
		/**
		 * 添加
		 */
		if ($n){
			$f = wsd::C('wapi_app', $f, 'aid'); if ($f['aid'] && $reply){
				/**
				 * 初始化自动回复模板
				 */
				$tpls = M('wapi/'.$reply)->replyTemplates(); is_array($tpls) || $tpls = array(); foreach ($tpls as $tpl){
					is_array($tpl) && count($tpl) && wsd::C('wapi_reply', array('aid' => $f['aid'], 'auid' => $p['auid'], 'rstatus' => (int) wsc::isarr($tpl, 'status'), 'rtype' => (int) wsc::isarr($tpl, 'type'), 'revent' => wsc::isarr($tpl, 'event'), 'rkeywords' => wsc::isarr($tpl, 'keywords'), 'rcontent' => wsc::isarr($tpl, 'content')));
				}
			}
		}
		/**
		 * 修改
		 */
		else {
			wsd::U('wapi_app', $f, array('aid' => $p['aid'], 'auid' => $p['auid']));
		}
		/**
		 * 返回记录
		 */
		return $f;
	}

	
	public function wreplyDecode($p){
		$t = S('WAPI_REPLY_TYPE');
		$p['rtypename'] = wsc::isarr($t, $p['rtype']);
		$p['rtypename'] || $p['rtypename'] = $p['rtype'];
		return $p;
	}
	/**
	 * 删除用户回复
	 * @param array $p, 接受参数
	 *              int rid, 回复ID
	 *              int aid, 隶属应用
	 *              int auid, 隶属用户
	 * @return array, 被删除回复
	 */
	public function wreplyDel($p){
		$r = array();
		/**
		 * 查询条件
		 */
		if (wsc::isarr($p, 'rid', '>0') || wsc::isarr($p, 'aid', '>0') || wsc::isarr($p, 'auid', '>0')){
			$r = $this->wreplyGet($p);
		}
		/**
		 * 读取列表
		 */
		if (wsc::isarr($r, '0.rid', '>0')){
			/**
			 * 删除回复
			 */
			foreach ($r as $ra){
				wsd::D('wapi_reply', array('rid' => $ra['rid']));
			}
		}
		/**
		 * 返回
		 */
		return $r;
	}
	/**
	 * 按应用读取已设置自动回复
	 * @param array $p, 接受参数
	 *              int rid, 回复编号
	 *              int aid, 隶属应用
	 *              int auid, 隶属用户
	 * @return array $r, 自动回复列表
	 */
	public function wreplyGet($p){
		$r = $w = array();
		/**
		 * 查询条件
		 */
		wsc::isarr($p, 'rid', '>0') && $w['r.rid'] = $p['rid'];
		wsc::isarr($p, 'aid', '>0') && $w['r.aid'] = $p['aid'];
		wsc::isarr($p, 'auid', '>0') && $w['r.auid'] = $p['auid'];
		/**
		 * 至少1个条件
		 */
		if (count($w) === 0){
			return $r;
		}
		/**
		 * 读取列表
		 */
		$s = array('from' => 'wapi_reply r', 'where' => $w);
		/**
		 * 分页
		 */
		if (wsc::isarr($p, 'page.href')){
			$s['page'] = $p['page'];
		}
		/**
		 * 返回
		 */
		return wsd::S($s, null, array($this, 'wreplyDecode'));
	}
	/**
	 * 变更状态
	 * @param array $p, 接受参数
	 *              int rid, 回复ID
	 *              int aid, 隶属应用
	 *              int auid, 隶属用户
	 * @return array, 变更后记录
	 */
	public function wreplyStatus($p){
		$r = array();
		/**
		 * 查询条件
		 */
		if (wsc::isarr($p, 'rid', '>0') || wsc::isarr($p, 'aid', '>0') || wsc::isarr($p, 'auid', '>0')){
			$r = $this->wreplyGet($p);
		}
		/**
		 * 读取列表
		 */
		if (wsc::isarr($r, '0.rid', '>0')){
			/**
			 * 更新状态
			 */
			foreach ($r as $rk => $ra){
				$ra['rstatus'] = $ra['rstatus'] ? 0 : 1;
				$r[$rk] = $ra;
				wsd::U('wapi_reply', array('rstatus' => $ra['rstatus']), array('rid' => $ra['rid']));
			}
		}
		/**
		 * 返回
		 */
		return $r;
	}

	
	
	/**
	 * 消息拉取PULL
	 * @example http://domain/?id=1
	 */
	public function wpull(){
		/**
		 * 应用存在检查
		 */
		$r = array(); $aid = (int) I('g.'.$this->_wpull_key); if ($aid){
			$p = wsd::S(array(
				'from' => 'wapi_app a, wapi w', 'where' => array(
					'a.aid' => $aid, 'a.astatus' => 1, array(
						'a.awid', 'w.wid', null, null, true
					), 'w.wstatus' => 1
				)
			)); if (wsc::isarr($p, '0.aid', '>0')){
				/**
				 * 用户已建立应用且已启用
				 */
				$r = M('wapi/'.$p[0]['wtype'])->apull($p[0]); if (wsc::isarr($r, 'openid')){
					/**
					 * 会话存储
					 */
					$save = wsc::isarr($r, 'save'); if (is_array($save) && count($save)){
						$userget = $this->userget($p[0], $r); if (wsc::isarr($userget, 'id', '>0')){
							/**
							 * 应用编号
							 * @var int wid, 全局应用ID
							 * @var int aid, 用户应用ID
							 */
							$r['save']['swid'] = $p[0]['wid'];
							$r['save']['said'] = $p[0]['aid'];
							$r['save']['suid'] = $userget['id'];
							/**
							 * 保存会话
							 */
							$this->usersave($p[0], $r['save']);
						}
					}
					/**
					 * 自动回复
					 * @note 自动回复时启用推送模式
					 */
					
				}
			}
		} return $r;
	}
	/**
	 * 将第3方数据转成公共数据
	 */
	protected function aformat($p){
	}
	/**
	 * 建立用户记录
	 * @note 首次拉取到第3方推送过来的消息时
	 *       添加用户记录
	 * @note 操作MySQL数据表wapi_user
	 * @param array $p, 接受参数
	 *              string openid, 第3方OpenID
	 */
	protected function user($p){
		
	}
	/**
	 * 获取任一用户的OpenHash唯一值
	 * @param array $p, 应用信息
	 * @param array $r, 拉取结果
	 * @return array, 会员账号(MySQL表wapi_user记录)
	 */
	private function userget(& $p, & $r, $ignore = false){
		$openhash = md5($p['wtype']."\t".$r['openid']);
		/**
		 * 用户已存在
		 */
		$u = wsd::R('wapi_user', array('aid' => $p['aid'], 'openhash' => $openhash), true); if (wsc::isarr($u, 'id', '>0')){
			return $u;
		}
		/**
		 * 重复出错了
		 */
		if ($ignore){
			return array('id' => 0);
		}
		/**
		 * 添加用户
		 */
		wsd::C('wapi_user', array('wid' => $p['wid'], 'aid' => $p['aid'], 'openid' => $r['openid'], 'openname' => $r['openname'], 'openavatar' => $r['openavatar'], 'openhash' => $openhash));
		/**
		 * 重复1次
		 */
		return $this->userget($p, $r, true);
	}
	/**
	 * 保存用户会话
	 * @param array $p, 应用配置
	 * @param array $r, 存储记录
	 * @return array, 最近一次存储记录
	 */
	private function usersave($p, $r){
		/**
		 * 写入存储记录
		 */
		$field = array('swid' => $r['swid'], 'said' => $r['said'], 'suid' => $r['suid']);
		$field['stime'] = time();
		$field = wsd::C('wapi_save', $field, 'sid');
		/**
		 * 新存储提醒
		 */
		if (wsc::isarr($r, 'save.remind')){
			$stats['savelast'] = time();
			$stats['savelastid'] = $field['sid'];
			$stats['savenews'] = '+1';
		}
		/**
		 * 存储总量统计
		 */
		$stats['savetotal'] = '+1';
		wsd::P('wapi_user', $stats, array('id' => $r['suid']));
		/**
		 * 返回存储
		 */
		return $field;
	}
	/**
	 * 回复会话
	 */
	private function userreply(){
	}
}